<template>
  <common-list>
    <common-search
      slot="search"
      @search="handleQuery"
      @reset="resetQuery"
      :otherSearch="true"
    >
      <el-form
        @submit.native.prevent
        v-model="queryParams"
        ref="queryForm"
        :inline="true"
        label-width="40px"
      >
        <el-form-item label="时间" prop="time">
          <el-date-picker
            popper-class="timePopper"
            v-model="queryParams.time"
            type="datetimerange"
            @change="dateChange"
            align="right"
            unlink-panels
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :picker-options="pickerOptions"
            :default-time="['00:00:00', '23:59:59']"
            :clearable="false"
            :editable="false"
          >
          </el-date-picker>
        </el-form-item>

        <el-form-item label="内容" prop="searchContent">
          <el-autocomplete
            clearable
            class="inline-input"
            v-model="queryParams.searchContent"
            value-key="columnAlias"
            :fetch-suggestions="querySearch"
            :trigger-on-focus="false"
            @select="handleSelect"
            @input="handleInput"
            @keyup.enter.native="handleQuery"
          ></el-autocomplete>
          <content-tip :tipType="'log_content'"></content-tip>
        </el-form-item>
      </el-form>

      <template slot="customSearch">
        <div
          class="custom-search"
          @click="showCustomSearch"
          :style="{ '--theme-color': systemInfo.theme }"
        >
          自定义查询
          <!--          <i class="iconfont icon-zidingyichaxun" style="font-size: 14px"></i>-->
          <commonIcon
            iconName="icon-zidingyichaxun"
            iconType="icon"
            isStyle
            iconSize="14"
          ></commonIcon>
        </div>
        <div
          class="custom-search"
          style="margin-left: 20px"
          :style="{ '--theme-color': systemInfo.theme }"
          @click="highSearch"
        >
          高级筛选
          <!--          <i class="iconfont icon-gaojishaixuan" style="font-size: 14px"></i>-->
          <commonIcon
            iconName="icon-gaojishaixuan"
            iconType="icon"
            isStyle
            iconSize="14"
          ></commonIcon>
        </div>
      </template>
    </common-search>

    <common-table
      v-loading="loading"
      slot="content"
      ref="logList"
      :data="logList"
    >
      <el-table-column
        label="采集时间"
        align="left"
        prop="createtime"
        width="180px"
      />
      <el-table-column label="内容" align="left" prop="content">
        <template slot-scope="scope">
          <Popover
            :label="'主机IP'"
            :type="'hostIp'"
            :typeValue="scope.row.hostIp"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'事件类型'"
            :type="'eventType'"
            :isScoller="isScoller"
            :typeValue="scope.row.eventType"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'源IP'"
            :type="'sourceIp'"
            :typeValue="scope.row.sourceIp"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'原始日志内容'"
            :type="'content'"
            :typeValue="scope.row.content"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'目标IP'"
            :type="'targetIp'"
            :typeValue="scope.row.targetIp"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'事件发生时间'"
            :type="'eventDate'"
            :typeValue="scope.row.eventDate"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
          <Popover
            :label="'资产类型编码'"
            :type="'softwareName'"
            :typeValue="scope.row.softwareName"
            :isScoller="isScoller"
            @changeScroller="changeScroller"
            @addToSearch="addToSearch"
          />
        </template>
      </el-table-column>
      <el-table-column label="操作" align="left" width="50px">
        <template slot-scope="scope">
          <el-button type="text" @click="showDetail(scope.row)"
            >详情
          </el-button>
        </template>
      </el-table-column>
    </common-table>

    <pagination
      slot="pagination"
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 详情 -->
    <common-info-dialog
      :infoLoading="infoLoading"
      :visible.sync="detailsOpen"
      @cancel="detailsOpen = false"
      :title="detailsTitle"
    >
      <Detail :detailForm="detailForm" />
    </common-info-dialog>

    <!-- 自定义查询 -->
    <common-edit-dialog
      :visible.sync="customOpen"
      @cancel="customOpen = false"
      @submit="customConfirm"
      :title="'自定义查询'"
    >
      <CustomFilter
        :customTreeData="customTreeData"
        :customTotalList="customTotalList"
        @getParentNodeData="getParentNodeData"
      />
    </common-edit-dialog>

    <!-- 高级筛选 -->
    <advanced-filter
      ref="advancedFilter"
      @toSubmit="toSubmit"
    ></advanced-filter>
  </common-list>
</template>

<script>
import { PICKOPTIONS } from "@/utils/constant";
import {
  fetchList,
  fetchDetail,
  fetchEventTypes,
  fetchCustomList,
} from "@/api/analysisCenter/log";
import AdvancedFilter from "./AdvancedFilter/index.vue";
import {
  generateSqlString,
  generateSqlObj,
  generateTuple,
  replaceOperator,
  setOperatorList,
} from "@/utils/util";
import { deepClone } from "@/utils/index";
import Popover from "./Popover/index.vue";
import Detail from "./Detail/index.vue";
import CustomFilter from "./CustomFilter/index.vue";
import ContentTip from "./ContentTip/index.vue";
import dayjs from "dayjs";
import BaseList from "@/mixins/BaseList";
import { mapGetters } from "vuex";
import commonIcon from "@/components/CommonIcon";

export default {
  name: "Log",
  mixins: [BaseList],
  components: {
    Popover,
    Detail,
    CustomFilter,
    AdvancedFilter,
    ContentTip,
    commonIcon,
  },
  data() {
    return {
      loading: true,
      total: 0,
      logList: [],

      detailsOpen: false,
      customOpen: false,
      detailsTitle: "详情",

      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        time: [
          new Date().getTime() - 24 * 60 * 60 * 1000,
          new Date().getTime(),
        ],
        searchContent: null,
        searchWhere: null,
        startDate: null,
        endDate: null,
      },
      lastTime: [
        new Date().getTime() - 24 * 60 * 60 * 1000,
        new Date().getTime(),
      ],

      detailForm: {},
      cuttentTime: "",

      pickerOptions: {
        shortcuts: PICKOPTIONS,
        //点击时，选择的是开始时间，也就是minDate
        onPick: ({ maxDate, minDate }) => {
          this.cuttentTime = minDate.getTime();
          if (maxDate) {
            //解除限制
            this.cuttentTime = "";
          }
        },
        disabledDate: (time) => {
          //是否限制的判断条件
          if (this.cuttentTime !== "") {
            const one = 30 * 24 * 3600 * 1000;
            const minTime = this.cuttentTime - one;
            const maxTime = this.cuttentTime + one;
            // console.log(time.valueOf() > Date.now());

            return time.getTime() < minTime || time.getTime() > maxTime;
          }
        },
      },

      highSearchOpen: false,

      customTreeData: [],
      customTotalList: [],
      typeMapList: [],
      oldTypes: [],
      infoLoading: false,
      originContentValue: "",
      isScoller: false, //是否滚动
    };
  },
  computed: {
    ...mapGetters(["systemInfo"]),
  },
  created() {
    this.getList();
    this.getEventTypes();
  },
  methods: {
    changeScroller() {
      this.isScoller = false;
    },
    getEventTypes() {
      fetchEventTypes().then((res) => {
        if (res && res.code === 200) {
          this.typeMapList = res.data || [];
          this.typeMapList.forEach((item) => {
            item.value = item.columnName;
            setOperatorList(item);
          });
          this.$store.commit("log/SET_TYPE_LIST", this.typeMapList);
        } else {
          this.typeMapList = [];
        }
      });
    },

    querySearch(queryString, cb) {
      if (queryString) {
        let queryArr = queryString.split(" ");
        queryString = queryArr[queryArr.length - 1];
        let typeList = this.typeMapList;
        let results = queryString
          ? typeList.filter(this.createFilter(queryString))
          : typeList;
        // 调用 callback 返回建议列表的数据
        cb(results);
      }
    },

    createFilter(queryString) {
      return (result) => {
        return result.columnAlias
          .toLowerCase()
          .includes(queryString.toLowerCase());
      };
    },

    dateChange() {
      if (this.queryParams.time && this.queryParams.time.length > 0) {
        let time1 = this.queryParams.time[0].getTime();
        let time2 = this.queryParams.time[1].getTime();
        if (time2 - time1 > 31 * 24 * 3600 * 1000) {
          this.queryParams.time = this.lastTime;
          return;
        }

        this.lastTime = this.queryParams.time;
      }
    },

    handleInput(val) {
      if (val) {
        let valArr = val.split(" ");
        valArr.pop();
        if (valArr && valArr.length > 0) {
          this.originContentValue = valArr.join(" ");
        }
      }
    },

    handleSelect(item) {
      this.queryParams.searchContent = this.originContentValue
        ? this.originContentValue.concat(" " + item.value)
        : this.originContentValue.concat(item.value);
    },

    // 查询日志列表
    getList() {
      this.loading = true;
      const time =
        "createtime >=" +
        dayjs(this.queryParams.time[0]).format("YYYY-MM-DD HH:mm:ss") +
        " AND createtime <=" +
        dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss");

      let query = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize,
        searchIndex: "index-bwda-ark-analysis-*",
        startDate: dayjs(this.queryParams.time[0]).format(
          "YYYY-MM-DD HH:mm:ss"
        ),
        endDate: dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss"),
      };

      query.searchWhere = this.queryParams.searchContent;

      if (query.searchWhere) {
        query.searchWhere = "(" + query.searchWhere + " AND " + time + ")";
      } else {
        query.searchWhere = "(" + time + ")";
      }
      fetchList(query)
        .then((res) => {
          if (res && res.code === 200) {
            if (res.data) {
              this.total = res.data.total;
              this.logList = res.data.list.reduce((r, c) => {
                if (c.eventType === "common") {
                  c.eventDate = "";
                }
                r.push({ ...c });
                return r;
              }, []);

              //监听table滚动
              this.$nextTick(() => {
                let tableBodyDom = this.$refs.logList.$refs.table.bodyWrapper;
                tableBodyDom.addEventListener("scroll", () => {
                  this.isScoller = true;
                });
              });
            } else {
              this.total = 0;
              this.logList = [];
            }
          } else {
            this.logList = [];
            this.total = 0;
            this.handleListTips(res);
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },

    //列表页点击 添加至搜索
    addToSearch(obj) {
      if (this.queryParams.searchContent) {
        if (obj.type === "content") {
          this.queryParams.searchContent =
            this.queryParams.searchContent.concat(
              " AND " + "(" + obj.type + " like )"
            );
        } else {
          this.queryParams.searchContent =
            this.queryParams.searchContent.concat(
              " AND " + "(" + obj.type + "=" + obj.typeValue + ")"
            );
        }
      } else {
        if (obj.type === "content") {
          this.queryParams.searchContent = "(" + obj.type + " like )";
        } else {
          this.queryParams.searchContent =
            "(" + obj.type + "=" + obj.typeValue + ")";
        }
      }
    },

    //展示自定义查询弹框
    showCustomSearch() {
      this.customOpen = true;
      this.customTreeData = [];
      this.customTotalList = [];
      this.$store.commit("log/SET_CHECKED_CACHE_LIST", {});
      fetchCustomList({
        multiAspectStatNames:
          "eventType;hostIp;targetIp;sourceIp;eventDetailName;SubCategory;eventName;AttackName;softwareName",
        startTime: dayjs(this.queryParams.time[0]).format(
          "YYYY-MM-DD HH:mm:ss"
        ),
        endTime: dayjs(this.queryParams.time[1]).format("YYYY-MM-DD HH:mm:ss"),
      })
        .then((res) => {
          if (res && res.code === 200) {
            res.data.forEach((item) => {
              this.customTreeData.push(item.summaryInfo);
              this.customTotalList.push(...(item.list || []));
              this.customTotalList.forEach((item, index) => {
                item.id = item.columnName + "_" + index;
              });
            });
            this.oldTypes = deepClone(this.customTreeData);
          } else {
            this.customTreeData = [];
            this.customTotalList = [];
          }
        })
        .catch(() => {
          this.customTreeData = [];
          this.customTotalList = [];
        });
    },

    //展示高级搜索弹框
    highSearch() {
      this.$refs.advancedFilter.show();
    },

    // 高级筛选确定
    toSubmit(relations) {
      this.$refs.advancedFilter.closeDialog();
      this.queryParams.searchWhere = generateSqlObj(relations);
      this.queryParams.searchContent = replaceOperator(
        generateSqlString(relations)
      );
    },

    // 自定义查询确定
    customConfirm() {
      this.customOpen = false;
      if (this.queryParams.searchContent === null)
        this.queryParams.searchContent = "";

      let checkedCache = this.$store.state.log.checkedCache;
      let keys = Object.keys(checkedCache);

      let values = keys.map((item) => {
        return checkedCache[item];
      });

      let result = { operate: "AND", chd: [] };
      const result2 = Object.entries(values).map(([k, v]) => {
        const chd = v.map((item) => {
          return {
            data: {
              fieldName: item.columnName,
              operator: "EQ",
              value: item.value,
            },
            operate: "OR",
          };
        });
        return {
          chd,
          operate: "OR",
        };
      });
      result.chd = result2;

      this.queryParams.searchContent = replaceOperator(
        generateSqlString(generateTuple(result), true)
      );
      this.queryParams.searchWhere = result;
    },

    getParentNodeData(val) {
      this.customTreeData = this.oldTypes.filter((item) => {
        return val
          ? item.columnAlias.toLowerCase().includes(val.toLowerCase())
          : true;
      });
    },

    //列表页详情
    showDetail(row) {
      this.infoLoading = true;
      fetchDetail({ indexName: row.indexName, docId: row.docId }).then(
        (res) => {
          this.infoLoading = false;
          if (res && res.code === 200) {
            this.detailForm = res.data;
            if (this.detailForm["事件类型"] === "common") {
              this.detailForm["事件发生时间"] = "";
            }

            this.detailsOpen = true;
          } else {
            this.$GlobalErrorConfirm("获取数据失败", res.msg);
          }
        }
      );
    },

    // 查询按钮操作
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },

    // 重置按钮操作
    resetQuery() {
      this.queryParams = this.$options.data().queryParams;
    },
  },
};
</script>
<style lang="scss">
.custom-search {
  color: var(--theme-color);
  cursor: pointer;
  font-size: 14px;
}

.timePopper.el-date-range-picker {
  .el-button--text {
    display: none;
  }
}

.el-autocomplete {
  width: 300px;
}
</style>
